home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / DIAG / INTR26B.ARJ / INTPRINT.C < prev    next >
C/C++ Source or Header  |  1990-10-14  |  18KB  |  645 lines

  1. /***********************************************************************/
  2. /* INTPRINT.C by Ralf Brown.  Donated to the Public Domain.           */
  3. /* Please do not remove my name from any copies or derivatives.        */
  4. /***********************************************************************/
  5. /* Program History:                               */
  6. /*   v1.00  4/23/89  initial public release                   */
  7. /*             with 4/30/89 list                       */
  8. /*   v1.10  5/21/89  added -I and -f                       */
  9. /*   v1.11  1/6/90   fixed #endif's for compilers which don't handle   */
  10. /*             labels                           */
  11. /*   v1.20  6/8/90   added -r                           */
  12. /*   v1.30  7/14/90  added -b, tables now stay aligned on odd indents  */
  13. /*   v1.40  10/6/90  added -B based on changes by Naoto Kimura, -w     */
  14. /***********************************************************************/
  15.  
  16. #include <stdio.h>
  17. #include <string.h>
  18.  
  19. #define VERSION "1.40"
  20.  
  21. #define MAXLINE 81   /* at most 80 chars per line (plus newline) */
  22. #define MAXPAGE 200  /* at most 200 lines per page */
  23.  
  24. #ifndef FALSE
  25. #define FALSE 0
  26. #endif
  27. #ifndef TRUE
  28. #define TRUE !FALSE
  29. #endif
  30.  
  31. #define EPSON_BOLD_ON    "\033E"
  32. #define EPSON_BOLD_OFF    "\033F"
  33. #define EPSON_ELITE_ON    "\033M"
  34. #define EPSON_ELITE_OFF "\033P"
  35. #define EPSON_LEFT_MARG "\033l"
  36.  
  37. #ifdef __TURBOC__
  38. #  define PROTOTYPES
  39. #  include <stdlib.h>
  40. int _Cdecl isatty(int handle) ;
  41. void _setenvp(void) {} /* don't need the environment, so don't include it */
  42. int isspace(char c) { return (c == ' ' || c == '\t') ; }
  43. #else
  44. /*#define PROTOTYPES  /* uncomment if compiler supports ANSI-style prototypes */
  45. #define _Cdecl
  46. #  include <ctype.h>
  47.  
  48. char *itoa(num,buf,radix)   /* not everybody has the same itoa() as TurboC */
  49. int num ;                   /* minimal implementation */
  50. char *buf ;
  51. int radix ;
  52. {
  53.    int count = 0 ;
  54.    int i ; 
  55.    char tmp ;
  56.  
  57.    do {
  58.       buf[count++] = '0' + num % radix ;
  59.       num = num / radix ;
  60.    } while (num) ;
  61.    buf[count] = '\0' ;
  62.    if (count > 1)
  63.       for (i = 0 ; i < count / 2 ; i++)
  64.          {
  65.          tmp = buf[i] ;
  66.          buf[i] = buf[count-i-1] ;
  67.          buf[count-i-1] = tmp ;
  68.          }
  69.    return buf ;
  70. }
  71. #endif /* __TURBOC__ */
  72.  
  73. /***********************************************/
  74.  
  75. #ifdef PROTOTYPES
  76. void usage(void) ;
  77. void indent_line(FILE *fp) ;
  78. void put_line(FILE *fp, int len) ;
  79. int divider_line(char *line) ;
  80. void output_line(char *line,FILE *fp) ;
  81. void fill_buffer(int lines, int lines_per_page) ;
  82. int find_page_break(int lines) ;
  83. void summarize(FILE *summary, int line, int pages_printed) ;
  84. void start_format(char *line) ;
  85. void print_line(char *line) ;
  86. void print_buffer(int first, int last, int lines_per_page, int total_lines, int use_FF) ;
  87. void _Cdecl main(int argc, char **argv) ;
  88. #endif /* PROTOTYPES */
  89.  
  90. /***********************************************/
  91.  
  92. char buffer[MAXPAGE][MAXLINE] ;
  93. char num[6] ;
  94. char summary_line[MAXLINE] ;
  95.  
  96. int pages_printed = 0 ;
  97. int indent = 0 ;
  98. int widow_length = 10 ;  /* number of lines to scan for good place to break */
  99. int page_numbers = FALSE ;
  100. int do_summary = FALSE ;
  101. int do_formats = FALSE ;
  102. int IBM_chars = FALSE ;
  103. int boldface = FALSE ;
  104. int Epson_bold = FALSE ;
  105. int echo_format = FALSE ;
  106. FILE *summary ;
  107. FILE *formats ;
  108.  
  109. int first_page = 0 ;
  110. int last_page = 9999 ;
  111.  
  112. /***********************************************/
  113.  
  114. void usage()
  115. {
  116.    fputs("INTPRINT v", stderr) ;
  117.    fputs(VERSION, stderr) ;
  118.    fputs(" by Ralf Brown.  Donated to the Public Domain.\n\n",stderr) ;
  119.    fputs("Usage: intprint [options] [lines [page_size]] <intlist >output\n",stderr) ;
  120.    fputs("\t'lines' defaults to 60\n",stderr) ;
  121.    fputs("\tif page_size is given, only linefeeds will be used to advance\n",stderr) ;
  122.    fputs("Options:\n",stderr) ;
  123.    fputs("\t-p\tadd page numbers\n",stderr) ;
  124.    fputs("\t-nN\tassume N pages have been printed from previous parts\n",stderr) ;
  125.    fputs("\t-rN:M\tprint only pages N through M\n",stderr) ;
  126.    fputs("\t-wN\tscan N lines from bottom of page for good place to break\n",stderr) ;
  127.    fputs("\t-e\tassume 'elite' mode (96 characters per line)\n",stderr) ;
  128.    fputs("\t-iN\tindent output N spaces\n",stderr) ;
  129.    fputs("\t-E\tspecifies that the printer is an Epson FX80 or compatible\n",stderr) ;
  130.    fputs("\t\t-E forces -e -i8\n",stderr) ;
  131.    fputs("\t-b\tboldface title lines and Return:/Note:\n",stderr) ;
  132.    fputs("\t-B\tboldface using Epson control codes instead of overprinting\n",stderr) ;
  133.    fputs("\t-I\tprinter supports IBM graphics characters\n",stderr) ;
  134.    fputs("\t-sfile\twrite a one-line-per-function summary to 'file'\n",stderr) ;
  135.    fputs("\t-ffile\twrite all data structures to 'file'\n",stderr) ;
  136.    exit(1) ;
  137. }
  138.  
  139. /***********************************************/
  140.  
  141. void indent_line(fp)
  142. FILE *fp ;
  143. {
  144.    int ind = indent ;
  145.  
  146.    while (ind >= 8)
  147.       {
  148.       fputc('\t',fp) ;
  149.       ind -= 8 ;
  150.       }
  151.    while (ind-- > 0)
  152.       fputc(' ', fp) ;
  153. }
  154.  
  155. /***********************************************/
  156.  
  157. void put_line(fp,len)
  158. FILE *fp ;
  159. int len ;
  160. {
  161.    int i ;
  162.  
  163.    if (IBM_chars)
  164.       for (i = 0 ; i < len ; i++)
  165.          fputc(196,fp) ;  /* single horizontal line */
  166.    else
  167.       for (i = 0 ; i < len ; i++)
  168.          fputc('-',fp) ;
  169. }
  170.  
  171. /***********************************************/
  172.  
  173. int divider_line(line)
  174. char *line ;
  175. {
  176.    return strncmp(line,"--------",8) == 0 ;
  177. }
  178.  
  179. /***********************************************/
  180.  
  181. void output_line(line,fp)
  182. char *line ;
  183. FILE *fp ;
  184. {
  185.    int pos = 0 ;
  186.    char bold[10] ;
  187.  
  188.    if (boldface)
  189.       {
  190.       if (strncmp(line,"INT ",4) == 0)
  191.      {
  192.      indent_line(fp) ;
  193.      if (Epson_bold)
  194.         {
  195.         fputs(EPSON_BOLD_ON,fp) ;
  196.         fputs(line,fp) ;
  197.         fputs(EPSON_BOLD_OFF,fp) ;
  198.         line = NULL ;
  199.         }
  200.      else
  201.         {
  202.         fputs(line,fp) ;
  203.         fputc('\r',fp) ;
  204.         }
  205.      }
  206.       else if (strncmp(line,"Return:",7) == 0 || strncmp(line,"Note:",5) == 0 ||
  207.            strncmp(line,"Notes:",6) == 0 || strncmp(line,"BUG:",4) == 0 ||
  208.            strncmp(line,"SeeAlso:",8) == 0)
  209.      {
  210.      strncpy(bold,line,sizeof bold) ;
  211.      *strchr(bold,':') = '\0' ;
  212.          indent_line(fp) ;
  213.      if (Epson_bold)
  214.         {
  215.         fputs(EPSON_BOLD_ON,fp) ;
  216.         fputs(bold,fp) ;
  217.         fputs(EPSON_BOLD_OFF,fp) ;
  218.         pos = strlen(bold) ;     /* we're no longer at the left edge of the */
  219.         line += pos ;         /* line, so figure out where we are */
  220.         }
  221.      else
  222.         {
  223.         fputs(bold,fp) ;
  224.         fputc('\r',fp) ;
  225.         }
  226.      }
  227.       }
  228.    if (line && *line)
  229.       {
  230.       if (pos == 0)        /* are we currently at the left edge of the line? */
  231.      indent_line(fp) ;  /* if yes, indent the desired amount */
  232.       if (indent % 8)
  233.      {
  234.      while (*line)
  235.         {
  236.         if (*line == '\t')
  237.            do {
  238.           fputc(' ',fp) ;
  239.           } while (++pos % 8) ;
  240.         else
  241.            {
  242.            fputc(*line,fp) ;
  243.            pos++ ;
  244.            }
  245.         line++ ;
  246.         }
  247.      }
  248.       else
  249.      fputs(line,fp) ;
  250.       }
  251.    fputc('\n',fp) ;
  252. }
  253.  
  254. /***********************************************/
  255.  
  256. void fill_buffer(lines,lines_per_page)
  257. int lines, lines_per_page ;
  258. {
  259.    int i, last ;
  260.  
  261.    if (lines)
  262.       for (i = lines ; i < lines_per_page ; i++)
  263.      strcpy(buffer[i-lines], buffer[i]) ;
  264.    else
  265.       lines = lines_per_page ;
  266.    for (i = lines_per_page - lines ; i < lines_per_page ; i++)
  267.       {
  268.       buffer[i][0] = '\0' ;  /* force empty line in case of EOF */
  269.       fgets(buffer[i], sizeof(buffer[i]), stdin) ;
  270.       last = strlen(buffer[i]) - 1 ;
  271.       if (last < 0)
  272.      last = 0 ;
  273.       if (buffer[i][last] == '\n')
  274.      buffer[i][last] = '\0' ;  /* strip the newline */
  275.       }
  276. }
  277.  
  278. /***********************************************/
  279.  
  280. int find_page_break(lines)
  281. int lines ;
  282. {
  283.    int i ;
  284.  
  285.    for (i = 0 ; i < widow_length ; i++)
  286.       {
  287.       if (strcmp(buffer[lines-i-1],"\n") == 0 ||
  288.           strlen(buffer[lines-i-1]) == 0 ||
  289.       divider_line(buffer[lines-i-1]))
  290.          return lines - i ;
  291.       }
  292.    return lines ;
  293. }
  294.  
  295. /***********************************************/
  296.  
  297. void summarize(summary, line, pages_printed)
  298. FILE *summary ;
  299. int line, pages_printed ;
  300. {
  301.    char *s ;
  302.    int i ;
  303.    int max_descrip ;
  304.    int len ;
  305.  
  306.    s = buffer[line] ;
  307.    if (strncmp(s, "INT ", 4) == 0)   /* start of an entry? */
  308.       {
  309.       summary_line[3] = summary_line[0] = ' ' ;
  310.       summary_line[1] = s[4] ;   /* output interrupt number */
  311.       summary_line[2] = s[5] ;
  312.       summary_line[4] = '\0' ;
  313.       len = 4 ;
  314.       s = buffer[line+1] ;
  315.       while (*s && isspace(*s))
  316.          s++ ;
  317.       if (strncmp(s,"AX",2) == 0)
  318.          i = 4 ;
  319.       else if (strncmp(s,"AH",2) == 0)
  320.          i = 2 ;
  321.       else
  322.          i = 0 ;
  323.       if (i)
  324.          {
  325.      while (*s && *s != '=')
  326.             s++ ;
  327.          s++ ;  /* skip the equal sign */
  328.          while (*s && isspace(*s))
  329.             s++ ;
  330.          if (strchr("0123456789ABCDEFabcdef",*s) != NULL)
  331.             {
  332.             summary_line[len++] = *s++ ;
  333.             summary_line[len++] = *s++ ;
  334.             summary_line[len++] = ' ' ;
  335.             if (i == 4)
  336.                {
  337.                summary_line[len++] = *s++ ;
  338.                summary_line[len++] = *s ;
  339.                }
  340.             else
  341.                {
  342.                summary_line[len++] = '-' ;
  343.                summary_line[len++] = '-' ;
  344.                }
  345.             summary_line[len++] = ' ' ;
  346.             }
  347.          else
  348.             {
  349.             /* wasn't legal digit, so no numbers */
  350.             strcpy(summary_line+len,"-- -- ") ;
  351.             len += 6 ;
  352.             }
  353.          }
  354.       else
  355.          {
  356.          strcpy(summary_line+len,"-- -- ") ;
  357.          len += 6 ;
  358.          }
  359.       if (page_numbers)
  360.          {
  361.      itoa(pages_printed,num,10) ;
  362.          for (i = strlen(num) ; i < 3 ; i++)
  363.             summary_line[len++] = ' ' ;
  364.          strcpy(summary_line+len,num) ;
  365.          len += strlen(num) ;
  366.          summary_line[len++] = ' ' ;
  367.          }
  368.       s = buffer[line] + 7 ;  /* find function description */
  369.       while (*s && !isspace(*s))
  370.          s++ ;
  371.       while (*s && isspace(*s))
  372.          s++ ;
  373.       max_descrip = (page_numbers ? MAXLINE-16 : MAXLINE-12) ;
  374.       for (i = 0 ; i < max_descrip && *s ; i++)
  375.          summary_line[len++] = *s++ ;
  376.       summary_line[len] = '\0' ;
  377.       if (do_summary)
  378.      output_line(summary_line,summary) ;
  379.       }
  380. }
  381.  
  382. /***********************************************/
  383.  
  384. void start_format(line)
  385. char *line ;
  386. {
  387.    indent_line(formats) ;
  388.    put_line(formats,79) ;
  389.    fputc('\n',formats) ;
  390.    indent_line(formats) ;
  391.    fputs(summary_line,formats) ;
  392.    fputc('\n',formats) ;
  393.    indent_line(formats) ;
  394.    fputc('\t',formats) ;
  395.    fputs(line+10,formats) ;
  396.    fputc('\n',formats) ;
  397.    echo_format = TRUE ;
  398. }
  399.  
  400. /***********************************************/
  401.  
  402. void print_line(line)
  403. char *line ;
  404. {
  405.    if (*line)
  406.       {
  407.       if (divider_line(line))
  408.          {
  409.      indent_line(stdout) ;
  410.          put_line(stdout,79) ;
  411.          fputc('\n', stdout) ;
  412.          echo_format = FALSE ;
  413.          }
  414.       else
  415.          {
  416.      output_line(line, stdout) ;
  417.          if (echo_format)
  418.         output_line(line,formats) ;
  419.          }
  420.       }
  421.    else
  422.       {
  423.       fputc('\n', stdout) ;
  424.       echo_format = FALSE ;
  425.       }
  426. }
  427.  
  428. /***********************************************/
  429.  
  430. void print_buffer(first,last,lines_per_page,total_lines,use_FF)
  431. int first, last, lines_per_page, total_lines ;
  432. int use_FF ;
  433. {
  434.    int i, ind ;
  435.  
  436.    pages_printed++ ;
  437.    for (i = first ; i < last ; i++)
  438.       {
  439.       if (pages_printed >= first_page && pages_printed <= last_page)
  440.      print_line(buffer[i]) ;
  441.       if (do_summary || do_formats)  /* need summary lines if doing formats */
  442.          summarize(summary,i,pages_printed) ;
  443.       if (do_formats && strncmp(buffer[i],"Format of ",10) == 0)
  444.          start_format(buffer[i]) ;
  445.       }
  446.    if (pages_printed >= first_page && pages_printed <= last_page)
  447.       {
  448.       if (page_numbers)
  449.      {
  450.      for (i = last - first ; i < lines_per_page - 1 ; i++)
  451.         fputc('\n', stdout) ;
  452.      indent_line(stdout) ;
  453.      for (ind = 0 ; ind < 38 ; ind++) /* normal indent + 38 spaces */
  454.         fputc(' ', stdout) ;
  455.      fputs("- ", stdout) ;
  456.      itoa(pages_printed, num, 10) ;
  457.      fputs(num, stdout) ;
  458.      fputs(" -\n", stdout) ;
  459.      }
  460.       if (use_FF)
  461.      fputc('\f', stdout) ;
  462.       else
  463.      for (i = page_numbers?lines_per_page:(last-first) ; i<total_lines ; i++)
  464.         fputc('\n', stdout) ;
  465.       }
  466. }
  467.  
  468. /***********************************************/
  469.  
  470. void _Cdecl main(argc,argv)
  471. int argc ;
  472. char *argv[] ;
  473. {
  474.    int lines_per_page = 60 ;
  475.    int total_lines = 66 ;
  476.    int use_FF = TRUE ;
  477.    int Epson_mode = FALSE ;
  478.    int last_line ;
  479.    int body_lines ;
  480.    char *summary_file = NULL ;
  481.    char *formats_file = NULL ;
  482.    char *last_page_num ;
  483.  
  484.    if (argc == 1 && isatty(0))
  485.       usage() ;   /* give help if invoked with no args and keybd input */
  486.    while (argc >= 2 && argv[1][0] == '-')
  487.       {
  488.       switch (argv[1][1])
  489.          {
  490.          case 'e':
  491.             indent = 8 ;
  492.             break ;
  493.          case 'E':
  494.             Epson_mode = TRUE ;
  495.             break ;
  496.          case 'I':
  497.             IBM_chars = TRUE ;
  498.             break ;
  499.          case 'p':
  500.             page_numbers = TRUE ;
  501.             break ;
  502.      case 'B':
  503.         Epson_bold = TRUE ;
  504.         /* fall through to -b */
  505.          case 'b':
  506.         boldface = TRUE ;
  507.         break ;
  508.          case 'n':
  509.         pages_printed = atoi(argv[1]+2) ;
  510.             break ;
  511.      case 'r':
  512.         first_page = atoi(argv[1]+2) ;
  513.         last_page_num = strchr(argv[1]+2, ':') ;
  514.         last_page = last_page_num ? atoi(last_page_num+1) : 0 ;
  515.         if (last_page == 0)
  516.            last_page = 9999 ;
  517.         break ;
  518.          case 'i':
  519.         indent = atoi(argv[1]+2) ;
  520.             break ;
  521.          case 's':
  522.             summary_file = argv[1]+2 ;
  523.             break ;
  524.          case 'f':
  525.             formats_file = argv[1]+2 ;
  526.             break ;
  527.      case 'w':
  528.         widow_length = atoi(argv[1]+2) ;
  529.         break ;
  530.          default:
  531.             usage() ;
  532.          }
  533.       argv++ ;
  534.       argc-- ;
  535.       }
  536.    if (summary_file && *summary_file)
  537.       if ((summary = fopen(summary_file, pages_printed ? "a":"w")) != NULL)
  538.          do_summary = TRUE ;
  539.       else
  540.      fputs("unable to open summary file\n", stderr) ;
  541.    if (formats_file && *formats_file)
  542.       if ((formats = fopen(formats_file, pages_printed ? "a":"w")) != NULL)
  543.          do_formats = TRUE ;
  544.       else
  545.      fputs("unable to open formats file\n", stderr) ;
  546.    if (argc >= 2)
  547.       lines_per_page = atoi(argv[1]) ;
  548.    if (argc == 3)
  549.       {
  550.       total_lines = atoi(argv[2]) ;
  551.       use_FF = FALSE ;
  552.       }
  553.    if (total_lines < lines_per_page)
  554.       {
  555.       total_lines = lines_per_page ;
  556.       use_FF = TRUE ;
  557.       }
  558.    if (argc > 3 || lines_per_page == 0) /* too many or non-numeric first param */
  559.       usage() ;
  560.    if (lines_per_page < 20 || lines_per_page > MAXPAGE)
  561.       {
  562.       fputs("Surely you jest!  At least 20 and at most 200 lines per page.\n\n", stderr) ;
  563.       usage() ;
  564.       }
  565.    if (widow_length < 3 || widow_length > lines_per_page / 2)
  566.       {
  567.       fputs("Widow lines (-w) must be set to at least 3 and at most one-half of the\n",stderr) ;
  568.       fputs("page length.  Using default of 10 lines.\n",stderr) ;
  569.       widow_length = 10 ;
  570.       }
  571. #ifdef __TURBOC__
  572.    setvbuf(stdin,NULL,_IOFBF,10240) ;  /* use larger disk buffers */
  573.    setvbuf(stdout,NULL,_IOFBF,10240) ; /* for better performance */
  574.    if (do_summary)
  575.       setvbuf(summary,NULL,_IOFBF,4096) ;
  576.    if (do_formats)
  577.       setvbuf(formats,NULL,_IOFBF,4096) ;
  578. #endif /* __TURBOC__ */
  579.    if (do_summary && pages_printed == 0)
  580.       {           /* create header, but only on first part */
  581.       indent_line(summary) ;
  582.       fputs("\t\t\t\tInterrupt Summary\n",summary) ;
  583.       indent_line(summary) ;
  584.       fputs("\t\t\t\t", summary) ;
  585.       put_line(summary,17) ;
  586.       fputs("\n\n",summary) ;
  587.       indent_line(summary) ;
  588.       fputs("INT AH AL", summary) ;
  589.       if (page_numbers)
  590.          fputs(" Page", summary) ;
  591.       fputs("\t\t\tDescription\n", summary) ;
  592.       indent_line(summary) ;
  593.       put_line(summary,79) ;
  594.       fputc('\n', summary) ;
  595.       }
  596.    if (do_formats && pages_printed == 0)
  597.       {           /* create header, but only on first part */
  598.       indent_line(formats) ;
  599.       fputs("\t\t\tData Structure Formats\n", formats) ;
  600.       indent_line(formats) ;
  601.       fputs("\t\t\t", formats) ;
  602.       put_line(formats,22) ;
  603.       fputs("\n\n", formats) ;
  604.       indent_line(formats) ;
  605.       fputs("INT AH AL", formats) ;
  606.       if (page_numbers)
  607.          fputs(" Page", formats) ;
  608.       fputs("\t\tData Structure\n", formats) ;
  609.       }
  610.    if (Epson_mode)
  611.       {
  612.       indent = 0 ;  /* -E overrides -e and -i */
  613.       fputs(EPSON_ELITE_ON,stdout) ;
  614.       fputs("\033l\007", stdout) ;
  615.       }
  616.    if (page_numbers)
  617.       body_lines = lines_per_page - 2 ;
  618.    else
  619.       body_lines = lines_per_page ;
  620.    last_line = 0 ;
  621.    while (!feof(stdin))
  622.       {
  623.       fill_buffer(last_line,body_lines) ;
  624.       last_line = find_page_break(body_lines) ;
  625.       print_buffer(0,last_line,lines_per_page,total_lines,use_FF) ;
  626.       }
  627.    if (last_line < body_lines)
  628.       print_buffer(last_line,body_lines,lines_per_page,total_lines,use_FF) ;
  629.    if (Epson_mode)
  630.       {
  631.       fputs(EPSON_ELITE_OFF,stdout) ;
  632.       fputs("\033l", stdout) ;       /* cancel Elite mode and indent */
  633.       fputc('\0', stdout) ;
  634.       }
  635.    fflush(stdout) ;
  636.    itoa(pages_printed, num, 10) ;
  637.    fputs(num, stderr) ;
  638.    fputs(" pages\n", stderr) ;
  639.    if (do_summary)
  640.       fclose(summary) ;
  641.    if (do_formats)
  642.       fclose(formats) ;
  643.    exit(0) ;
  644. }
  645.